Gametype Editor Source
http://wiki.fpsgamers.se/index.php/Halo/GameTypeEditSource

Author: ZiON
Language: Borland Delphi (v3-v7 should work)
State: OpenSource

Type's
 Type
  // TBlam? the record (or struct) of the important part of the blma.lst
  // It's not updated ... really... yet...
  TBlam? = packed Record
    Name : Array[0..47] of char;
    Gametype : Byte;
    Unk2 : Array[49..55] of byte;
    Parameters : Byte;
    Unk3 : array[57..59] of byte;
    ObjectivesIndicator? : Byte;
    Unk4 : array[61..63] of byte;
    OddManOut? : Byte;
    Unk5 : array[65..67] of byte;
    RespawnTimeGrowth? : Longword;
    RespawnTime? : LongWord?;
    SuicidePenalty? : LongWord?;
    NoOfLives? : Byte;
    Unk6 : Array[81..86] of byte;
    Unk7 : Byte;
    ScoreLimit? : Longword;
    WeaponSet? : Byte;
    Unk9 : Array[93..95] of byte;
    RedVehicles? : Longword;
    BlueVehicles? : Longword;
    VehicleRespawnTime? : Longword;
    FriendlyFire : byte;
    Unk10 : array[109..111] of byte;
    FriendlyFirePenalty? : Longword;
    TeamBalance? : byte;
    Unk11 : Array[117..119] of byte;
    TimeLimit? : Longword;
    Unk11a : Byte;
    Unk12 : byte;
    Unk12a : byte;
    Unk12b : byte;
    Unk12c : Word;
    Unk13 : Array[130..148] of byte;
    Unk14 : byte;
    Unk15 : Word;
    OldCRC? : Longword;
    Assault : Byte;
    Unk17 : byte;
    FlagMustReset? : byte;
    FlagAtHomeToScore? : Byte;
    SingleFlag? : Longword;
    Unk18 : array[164..215] of byte;
    CRC : LongWord?;
  end;

Const's
 const
  CRCPOLY = $EDB88320;     // The crcpoly used in Halo 

Global Vars
 var
  CRCTable?: array[0..512] Of Longint;  // CRC array to hold the CRCTable?
  Blam : TBlam?;                        // The blam.lst  

Procedure's

// CRC Stuff 

 procedure BuildCRCTable?;  // Build the CRC table's
 var
  i, j: Word;
  r: Longword;
 begin
  FillChar?(CRCTable?, SizeOf?(CRCTable?), 0);
  for i := 0 to 255 do
  begin
    r := i shl 1;
    for j := 8 downto 0 do
      if (r and 1) <> 0 then
        r := (r Shr 1) xor CRCPOLY
      else
        r := r shr 1;
    CRCTable?[i] := r;
   end; end;

 function RecountCRC?(b: byte; CrcOld?: Longint): Longint;
 begin
  RecountCRC? := CRCTable?[byte(CrcOld? xor Longint(b))] xor ((CrcOld? shr 8) and $00FFFFFF)
 end;

 function GetCRC32?: Longword;  // Calculates the CRC of the Blam var
 var
  Buffer: array[0..SizeOf?(TBlam?)-4-1] of Byte;  // Byte buffer of Blam
  CRC: Longword;
  i: Integer;
 begin
  BuildCRCTable?;
  CRC := $FFFFFFFF;

  Move(Blam, Buffer, SizeOf?(Buffer)-1);  // some dirty memory moving

  for i := 0 to SizeOf?(Buffer)-1 do      // Count the actual CRC from the Buffer
   CRC := RecountCRC?(Buffer[i], CRC);

  CRC := Not CRC;
  Result := CRC;
 end;

// Custom functions for setting stuff in the Blam 

 Function VehicleValue?(value : longword; num:Byte):Byte;
 Begin
  Case num of
    0 : result:=(value and 7);  //
    1 : result:=(value and 14) shr 1;  //
    2 : result:=(value and 112) shr 4;  //
    3 : result:=(value and 896) shr 7;  //
    4 : result:=(value and 7168) shr 10;  //
    5 : result:=(value and 57344) shr 13;  //
    6 : result:=(value and 458752) shr 16;  //
    7 : result:=(value and 3670016) shr 19;  //
  end;
 end;

 Function SetVehicleValue?(Setting: Longword; VSet?, Hogs, Ghosts, Banshees, Tanks, RocketHogs?, Turrets : Byte):Longword;
 Begin
  // VehicleSet?
  Setting:=Setting AND Not(7);
  Setting:=Setting OR VSet?;

  // Hogs
  Setting:=Setting AND Not(112);
  Setting:=Setting OR (Hogs shl 4);

  // Ghosts
  Setting:=Setting AND Not(896);
  Setting:=Setting OR (Ghosts shl 7);

  // Tanks
  Setting:=Setting AND Not(7168);
  Setting:=Setting OR (Tanks shl 10);

  // Rockethogs
  Setting:=Setting AND Not(57344);
  Setting:=Setting OR (RocketHogs? shl 13);

  // Banshees
  Setting:=Setting AND Not(458752);
  Setting:=Setting OR (Banshees shl 16);

  // Turrets
  Setting:=Setting AND Not(3670016);
  Setting:=Setting OR (Turrets shl 19);

  Result:=Setting;
 end;

// Example stuff on loading saving 

 // Common init stuff
 procedure TForm1.FormCreate?(Sender: TObject?);
 begin
   ms:=TMemoryStream?.Create;
 end;

 procedure TForm1.FormDestroy?(Sender: TObject?);
 begin
   ms.free;
 end;

 procedure TForm1.LoadBlamFromFile?(FileName?:string);
 begin
   ms.LoadFromFile?(OpenDialog1?.Filename);
   ms.Seek(0, soFromBeginning);
   ms.Read(Blam, SizeOf?(TBlam?));
 end;

 procedure TForm1.SaveBlamToFile?(FileName?:String);
 begin
   ms.Seek(0, soFromBeginning);
   ms.Write(Blam, SizeOf?(TBlam?));
   ms.SaveToFile?(FileName?);

   Application.MessageBox?('Gametype updated successfully!', 'Message', MB_ICONINFORMATION);
 end;

// Example load, change, save 
 procedure TForm1.DoProcess?;
 begin
   LoadBlamFromFile?('blam.lst');

   Blam.ScoreLimit?:=15;
   Blam.TimeLimit?:=81000;
   Blam.VehicleRespawnTime?:=9000;
   Blam.Assault:=0;
   Blam.FlagMustReset?:=0;
   Blam.FlagAtHomeToScore?:=0;

   SaveBlamToFile?('blam.lst');
 end;

Credits

Goes to Kybo Ren for doing the inital research on the file format of the blam.lst 


--------------------------------------------------------------------------------
Kybo Ren says: Here is the source for my gametype editor. It is written in C++, using 
the Microsoft Foundation Class wrapper for the win api. (Get it here) 
http://wiki.fpsgamers.se/uploads/Halo/EditHaloGametypes_source.zip
